/*
 * Copyright (c) 2024 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#ifndef ARMV8A_CONTEXT_H
#define ARMV8A_CONTEXT_H

#include <arch/regs.h>
#include <stdlib/stdint.h>

typedef struct context {
    uint64_t spsr;
    uint64_t sp_el0;
    uint64_t elr;
    uint64_t regs[REGS_COUNT];
} context_t;

static inline unsigned long context_get_reg(context_t *ctx, unsigned int rx)
{
    return ctx->regs[rx];
}
static inline unsigned long context_get_sp(context_t *context)
{
    return context->regs[SP];
}
static inline unsigned long context_get_pc(context_t *ctx)
{
    return context_get_reg(ctx, PC);
}
static inline unsigned long context_get_retcode(context_t *ctx)
{
    return context_get_reg(ctx, X0);
}
static inline void context_prepare_exit(context_t *ctx)
{
    (void)ctx;
}
static inline void context_set_spsr(context_t *ctx, uint64_t value)
{
    ctx->spsr = value;
}

void      context_init(context_t *context, int type);
void      context_set_stack(context_t *context, void *stack, uint32_t stack_size);
void      context_set_ipcbuffer(context_t *context, void *ipcbuffer);
void      context_set_retcode(context_t *context, uint64_t retcode);
void      context_set_reg_param(context_t *context, uint64_t p0, uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4,
                                uint64_t p5, uint64_t p6, uint64_t p7);
void      context_set_entry(context_t *context, uint64_t entry);
void      context_restore_current(void);
uint64_t *current_context_nill(void);

#endif
